package com.test.mchelepesa.util_rice.http_rice.connection;

import android.os.Handler
import android.os.Looper
import com.test.mchelepesa.constant_rice.Constant_rice
import java.io.*
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLConnection
import java.util.UUID
import java.util.concurrent.ExecutorService
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import javax.net.ssl.HttpsURLConnection
import kotlin.math.min

/** 专门处理业务线程池 */
class BusinessHttpConnection(private val fullUrl: String, private val body: String) {

    companion object {
        private val mainHandler = Handler(Looper.getMainLooper())

        private var cpuCount: Int = Runtime.getRuntime().availableProcessors() + 1
        private var calculatedMax: Int = cpuCount * 2 + 1
        private var maxPoolSize: Int = min(8, calculatedMax)
        
        private val cachedThreadPool: ExecutorService = ThreadPoolExecutor(
            0, // 线程池空闲时会不保留线程
            maxPoolSize, // 最大并发线程数
            60L, // 线程空闲时最大存活时间
            TimeUnit.SECONDS, // 空闲时间单位
            LinkedBlockingQueue(10), // 队列大小，最多允许 32 个任务排队
            ThreadPoolExecutor.DiscardPolicy() // 任务队列已满时丢弃任务
        )

        fun shutdown() {
            try {
                cachedThreadPool.shutdownNow()
            } catch (_: Exception) {
            }
        }
    }

    fun fetch(
        method: String = "POST",
        onSuccess: (String) -> Unit?,
        onFailure: (Int, String) -> Unit?,
        silent: Boolean = false
    ) {

        cachedThreadPool.execute {
            try {
                val urlConnection = initConnection(method)
                urlConnection.outputStream?.use { os ->
                    os.write(body.toByteArray(Charsets.UTF_8))
                    os.flush()
                    os.close()
                }
                try {
                    val resCode = urlConnection.responseCode
                    if (resCode == HttpURLConnection.HTTP_OK) {
                        // 如果不需要处理回调，直接退出
                        if (silent) return@execute

                        val ins = urlConnection.inputStream
                        val reader = BufferedReader(InputStreamReader(ins))
                        val result = StringBuilder()
                        var line: String?
                        while ((reader.readLine().also { line = it }) != null) {
                            result.append(line)
                        }
                        mainHandler.post {
                            onSuccess.invoke(result.toString())
                        }
                    } else {
                        // 如果不需要处理回调，直接退出
                        if (silent) return@execute

                        mainHandler.post {
                            onFailure.invoke(resCode, urlConnection.responseMessage)
                        }
                    }
                } catch (e: Exception) {
                    // 如果不需要处理回调，直接退出
                    if (silent) return@execute

                    mainHandler.post {
                        onFailure.invoke(-1, e.localizedMessage ?: "Unknown error")
                    }
                } finally {
                    try {
                        urlConnection.inputStream.close()
                        urlConnection.disconnect()
                    } catch (_: Exception) {
                    }
                }
            } catch (e: IOException) {
                // 如果不需要处理回调，直接退出
                if (silent) return@execute

                mainHandler.post {
                    onFailure.invoke(-1, e.localizedMessage ?: "Unknown error")
                }
                // StringUtil_rice.printException(e)
            }
        }
    }

    fun uploadFile(
        filePath: String,
        onSuccess: (String) -> Unit?,
        onFailure: (Int, String) -> Unit?
    ) {
        cachedThreadPool.execute {
            val boundary = UUID.randomUUID().toString()
            val twoHyphens = "--"
            val lineEnd = "\r\n"
            val file = File(filePath)

            if (!file.exists()) {
                mainHandler.post {
                    onFailure.invoke(-1, "File not found: $filePath")
                }
                return@execute
            }

            try {
                val urlConnection = initConnection()
                urlConnection.setRequestProperty(
                    "Content-Type",
                    "multipart/form-data; boundary=$boundary"
                )

                val contentType =
                    URLConnection.guessContentTypeFromName(file.name) ?: "application/octet-stream"
                val outputStream = DataOutputStream(urlConnection.outputStream)

                // 写入 multipart 表单头部
                outputStream.writeBytes("$twoHyphens$boundary$lineEnd")
                outputStream.writeBytes("Content-Disposition: form-data; name=\"image\"; filename=\"${file.name}\"$lineEnd")
                outputStream.writeBytes("Content-Type: $contentType$lineEnd")
                outputStream.writeBytes(lineEnd)

                // 读取文件数据
                val fileInputStream = FileInputStream(file)
                val buffer = ByteArray(4096)
                var bytesRead: Int
                while (fileInputStream.read(buffer).also { bytesRead = it } != -1) {
                    outputStream.write(buffer, 0, bytesRead)
                }
                fileInputStream.close()

                outputStream.writeBytes(lineEnd)
                outputStream.writeBytes("$twoHyphens$boundary$twoHyphens$lineEnd")
                outputStream.flush()
                outputStream.close()

                try {
                    val responseCode = urlConnection.responseCode
                    val responseMessage = urlConnection.responseMessage
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        val reader = BufferedReader(InputStreamReader(urlConnection.inputStream))
                        val result = StringBuilder()
                        var line: String?
                        while ((reader.readLine().also { line = it }) != null) {
                            result.append(line)
                        }
                        reader.close()
                        mainHandler.post {
                            onSuccess.invoke(result.toString())
                        }
                    } else {
                        mainHandler.post {
                            onFailure.invoke(responseCode, responseMessage)
                        }
                    }
                } catch (e: Exception) {
                    mainHandler.post {
                        onFailure.invoke(-1, e.localizedMessage ?: "Unknown error")
                    }
                } finally {
                    try {
                        urlConnection.inputStream.close()
                        urlConnection.disconnect()
                    } catch (_: Exception) {
                    }
                }
            } catch (e: Exception) {
                mainHandler.post {
                    onFailure.invoke(-1, e.localizedMessage ?: "Unknown error")
                }
            }
        }
    }

    @Throws(IOException::class)
    private fun initConnection(method: String = "POST"): HttpURLConnection {
        val url = URL(this.fullUrl)
        val urlConnection = url.openConnection() as HttpsURLConnection
        urlConnection.doInput = true
        urlConnection.doOutput = true
        urlConnection.useCaches = false
        urlConnection.readTimeout = 60000
        urlConnection.connectTimeout = 60000
        urlConnection.requestMethod = method
        urlConnection.setRequestProperty("Charset", "UTF-8")
        urlConnection.setRequestProperty("Connection", "Keep-Alive")
        urlConnection.setRequestProperty("Content-Type", "application/json")
        urlConnection.setRequestProperty("product", Constant_rice.PRODUCT)
        return urlConnection
    }
}
